/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2025-06-28     17247       the first version
 */

#include <rtthread.h>
#include <rtdevice.h>
#include "uart_protocol.h"

#define UART0_NAME       "uart0"
#define MAX_DATA_LEN     256  // 数据最大长度
#define RX_BUFFER_SIZE   512

/* 帧头、帧尾定义 */
#define FRAME_HEADER_1   0x53
#define FRAME_HEADER_2   0x59
#define FRAME_TAIL_1     0x54
#define FRAME_TAIL_2     0x43

/* 使用中断模式 */
static struct rt_semaphore rx_sem0;
static rt_device_t serial0;
static rt_thread_t uart0_thread;

/* 接收缓冲区 */
static rt_uint8_t rx_pool[RX_BUFFER_SIZE];

static struct rt_ringbuffer rx_rb;

/* 接收回调函数 */
static rt_err_t uart0_input(rt_device_t dev, rt_size_t size)
{
    rt_sem_release(&rx_sem0);
    return RT_EOK;
}

/**
 * @brief UART0 接收线程入口
 */
static void uart0_thread_entry(void *parameter)
{
    rt_uint8_t ch;

    // 初始化环形缓冲区
    rt_ringbuffer_init(&rx_rb, rx_pool, RX_BUFFER_SIZE);

    while (1)
    {
        /* 等待接收信号量 */
        if (rt_sem_take(&rx_sem0, RT_WAITING_FOREVER) != RT_EOK)
            continue;

        /* 从串口读取一个字节 */
        while (rt_device_read(serial0, -1, &ch, 1) == 1)
        {
            rt_ringbuffer_put_force(&rx_rb, &ch, 1);
        }

        /* 查找并解析完整帧 */
        parse_frame_from_buffer();
    }
}

/**
 * @brief 发送数据到UART0
 *
 * @param data 要发送的数据指针
 * @param size 数据大小
 */
void uart0_send(const void *data, rt_size_t size)
{
    if (serial0 && rt_device_write(serial0, 0, data, size) != size)
    {
        rt_kprintf("[UART0] Send failed\n");
    }
}

/**
 * @brief UART0 初始化函数（中断模式）
 *
 * @return int RT_EOK(0) 表示成功，其他值表示错误
 */
static int uart0_init(void)
{
    rt_err_t ret = RT_EOK;
    char uart_name[RT_NAME_MAX];
    char init_msg[] = "UART0 (Interrupt mode) ready!\r\n";

    /* 使用默认串口名称 */
    rt_strncpy(uart_name, UART0_NAME, RT_NAME_MAX);

    /* 查找串口设备 */
    serial0 = rt_device_find(uart_name);
    if (!serial0)
    {
        rt_kprintf("[UART0] Device %s not found!\n", uart_name);
        return -RT_ERROR;
    }

    /* 初始化信号量 */
    rt_sem_init(&rx_sem0, "rx0_sem", 0, RT_IPC_FLAG_FIFO);

    /* 打开设备 - 中断接收模式 */
    if (rt_device_open(serial0, RT_DEVICE_FLAG_INT_RX) != RT_EOK)
    {
        rt_kprintf("[UART0] Open device failed!\n");
        return -RT_ERROR;
    }

    /* 设置接收回调函数 */
    rt_device_set_rx_indicate(serial0, uart0_input);

    /* 创建接收线程 */
    uart0_thread = rt_thread_create("uart0_rx", uart0_thread_entry,
    RT_NULL, 1024, 25, 10);

    if (uart0_thread)
    {
        rt_thread_startup(uart0_thread);
        rt_kprintf("[UART0] Initialized successfully with interrupt mode\n");

        // 发送初始化成功消息
        uart0_send(init_msg, sizeof(init_msg) - 1);
    }
    else
    {
        rt_kprintf("[UART0] Thread create failed!\n");
        ret = -RT_ERROR;
    }

    return ret;
}

void parse_frame_from_buffer(void)
{
    enum {
        STATE_SYNC_1,
        STATE_SYNC_2,
        STATE_READING
    } state = STATE_SYNC_1;

    rt_uint8_t byte;
    static rt_uint8_t frame_buf[256];
    rt_size_t offset = 0;

    while (rt_ringbuffer_data_len(&rx_rb) > 0)
    {
        rt_ringbuffer_get(&rx_rb, &byte, 1);

        switch (state)
        {
        case STATE_SYNC_1:
            if (byte == FRAME_HEADER_1)
                state = STATE_SYNC_2;
            break;

        case STATE_SYNC_2:
            if (byte == FRAME_HEADER_2) {
                frame_buf[0] = FRAME_HEADER_1;
                frame_buf[1] = FRAME_HEADER_2;
                offset = 2;
                state = STATE_READING;
            } else {
                state = STATE_SYNC_1; // 回退重新寻找帧头
            }
            break;

        case STATE_READING:
            frame_buf[offset++] = byte;

            if (offset >= 2 && offset >= (frame_buf[4] | (frame_buf[5] << 8)) + 8) {
                // 完整帧接收完成，调用解析函数
                parse_frame(frame_buf, offset);
                offset = 0;
                state = STATE_SYNC_1;
            }
            if (offset >= sizeof(frame_buf)) {
                // 缓冲区满，丢弃当前帧
                offset = 0;
                state = STATE_SYNC_1;
            }
            break;
        }
    }
}

/* 使用设备级初始化 */
INIT_DEVICE_EXPORT(uart0_init);


